home *** CD-ROM | disk | FTP | other *** search
- /*[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]*/
- /* UPatch.p */
- /* Copyright © 1985-1990 by Apple Computer, Inc. All rights reserved. */
- /*[f-]*/
- /*
- T H E O R Y O F O P E R A T I O N
- This unit implements a general trap-patching mechanism. Two types of
- patches are implemented:
- Normal Patch The trap is patched such that it jumps to the routine
- of your choice, ignoring the routine it previously
- jumped to. On a 128K ROM machine, the patch is made
- by setting the trap address to your routine. On a 64K
- machine, a small block of code is allocated in the
- system heap: The trap address is set to point to the
- block, and the block contains code to jump to your
- routine.
- Head Patch The trap is patched such that it jumps to the
- routine of your choice, then jumps to the trap's
- routine. Head patches come in two flavors: with
- no parameters and with one long-word parameter. The
- patch is made by allocating a small block of code in
- the application heap (system heap for 64K ROMs). The
- trap address is set to the block, and the block contains
- code to jump to your routine and return to the trap's
- original address.
- References to patches are kept in TrapPatch records. For each trap
- patched you must define a variable of type TrapPatch. This unit links
- the TrapPatch records to form a linked list for facilitate unpatching
- all patches without specifying each individual patch.
- */
- /*[f+]*/
- #ifndef __UPatch__
- #define __UPatch__ 0
- #endif
- #if ! __UPatch__
- #define __UPatch__ 1
-
- /* • Auto-Include the requirements for this unit's interface. */
- #ifndef __TYPES__
- #include "Types.h"
- #endif
- #ifndef __MEMORY__
- #include "Memory.h"
- #endif
-
- /* Preferred. The pointer type _MUST_ be
- declared first since the record is self
- referential */
- typedef struct TrapPatch *TrapPatchPtr;
- struct TrapPatch {
- Ptr jmpPtr; /* Addr of sys heap block */
- short trapNum; /* trap # being patched */
- long oldTrapAddr; /* old trap address */
- TrapPatchPtr nextPatch; /* next link in linked list of patches */
- };
-
- struct CallBack {
- short saveRtnAdd; /* Internal use */
- short moveRefCon; /* Internal use */
- long refCon; /* the refCon that will be passed as last
- parm */
- short targOffset; /* Internal use */
- short jmpInst; /* Internal use */
- long jmpTarg; /* Internal use */
- };
- typedef CallBack *CallBackPtr;
-
- /* The following variable is really private but is in the interface just in case
- you're doing something really wierd and you really need it */
-
- extern pascal TrapPatchPtr pPatchList; /* Head of linked list of patches */
-
- extern pascal void InitUPatch(void);
- /* Call this once to set things up. Initializes the linked list of patches to NIL. */
-
- extern pascal void EachPatchDo(pascal Boolean (*DoToPatch)(TrapPatchPtr thePatchPtr, void *
- DoToPatch_StaticLink), void *DoToPatch_StaticLink);
- /* Calls DoToPatch for each patch in the list from pPatchList to the last patch.
- Stops at end of list or when DoToPatch returns TRUE. DoToPatch may not remove patches. */
-
- extern pascal short HeadPatch(TrapPatch *thePatch, short theTrapNum, Ptr theRoutine);
- /* HeadPatch patches a trap such that it calls theRoutine first, then executes the old trap
- routine. theRoutine must be a procedure with no arguments. This type of patch is
- implemented by setting up a block in the system heap, patching the trap to jump to the
- block, and inserting code in the block that pushes the original trap address on the stack
- and jumps to theRoutine. Thus, theRoutine returns to the original trap routine. */
-
- extern pascal short Head1Patch(TrapPatch *thePatch, short theTrapNum, Ptr theRoutine);
- /* Head1Patch is just like HeadPatch, except that it is intended to patch traps with a s
- ingle
- long-word parameter. The parameter passed to the trap is also passed to theRoutine.
- theRoutine must be a procedure with one long-word parameter. */
-
- extern pascal short PatchTrap(TrapPatch *thePatch, short theTrapNum, Ptr theRoutine);
- /* PatchTrap patches the given trap to theRoutine. On a 64K ROM machine, we must set up a
- block in the system heap, patch the trap to jump to the block, and insert code in the block
- to jump to theRoutine. */
-
- extern pascal void SetCallBack(Ptr targProc, long itsRefCon, CallBackPtr theCallBackPtr);
- /* Prepares a call back record for use. Stuffs in the target of the call back and the r
- efcon
- to pass as an _additional_ and _last_ parameter to it. Useful for getting conte
- xt when being
- called back from the toolBox. Also useful for avoiding use of globals when gett
- ing context */
-
- extern pascal void UnpatchTrap(TrapPatch *thePatch);
- /* UnpatchTrap unpatches the given trap. */
-
- extern pascal void UnpatchAll(void);
- /* UnpatchAll unpatches all traps. */
- #endif
-
-